﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using JetBrains.Annotations;
using WikiDoc.Formatter;
using WikiDoc.Reader;

namespace WikiDoc
{
    /// <summary>
    /// 
    /// </summary>
    public class XmlDocWalker
    {
        /// <summary>
        /// 捕获 XmlDoc 中的 summary, remarks, returns 等片段
        /// </summary>
        public static readonly Regex SectionRegex = new Regex(
            @" (?<pre> <summary>)    (?<content> .*?) (?<post> \s* </summary>)" +
            @"|(?<pre> <remarks>)    (?<content> .*?) (?<post> \s* </remarks>)" +
            @"|(?<pre> <returns>)    (?<content> .*?) (?<post> \s* </returns>)" +
            @"|(?<pre> <value>)      (?<content> .*?) (?<post> \s* </value>)" +
            @"|(?<pre> <exception[^>]*>) (?<content> .*?) (?<post> \s* </exception>)" +
            @"",
            RegexOptions.Compiled 
            | RegexOptions.IgnorePatternWhitespace
            | RegexOptions.CultureInvariant
            | RegexOptions.Singleline);

        /// <summary>
        /// 要处理的 XmlDoc Tag 标签
        /// </summary>
        public static string[] Sections = {"summary", "remarks", "returns", "value", "exception"};

        /// <summary>
        /// 转换指定的 XmlDoc
        /// </summary>
        /// <param name="xmldoc">The xmldoc.</param>
        /// <param name="translater">The translater.</param>
        /// <param name="formatter">The formatter.</param>
        /// <returns></returns>
        [NotNull]
        public static string TranslateXmlDoc([NotNull] string xmldoc, [CanBeNull] WikiTranslater translater, [CanBeNull] IFormatter formatter )
        {
            if (xmldoc == null) throw new ArgumentNullException("xmldoc");

            translater = translater ?? new WikiTranslater();
            formatter = formatter ?? new XmlDocFormatter();

            var sb = new StringBuilder();
            var writer = new StringWriter(sb);
            var newlineChars = new[] {'\r', '\n'};

            return SectionRegex.Replace(
                xmldoc,
                match =>
                    {
                        sb.Length = 0;
                        formatter.Writer = writer;
                        formatter.Reset();

                        var content = match.Groups["content"].Value;
                        var multiLine = content.IndexOfAny(newlineChars) >= 0;

                        sb.Append(match.Groups["pre"].Value);
                        
                        if (multiLine)
                        {
                            sb.AppendLine();
                        }

                        translater.Parse(new SectionReader(content), formatter);

                        sb.Append(match.Groups["post"].Value);

                        return sb.ToString();
                    });
        }
    }
}
